vimfandomcom-20200223-history
Ranges
A range permits a command to be applied to a group of lines in the current buffer. For most commands, the default range is the current line. For example: *:s/old/new/g changes all old to new in the current line *:11,15s/old/new/g changes lines 11 to 15 inclusive *:%s/old/new/g changes all lines Examples A range can be specified using line numbers or special characters, as in these examples: The :s/// command substitutes in the specified lines. The :w command writes a file. On its own, :w writes all lines from the current buffer to the file name for the buffer. Given a range and a file name, :w writes only the specified lines to the specified file. The example above creates file single.txt containing the current line. If you know you want to substitute in six lines, starting from the current line, you can use either of the ranges shown above. An easier method is to enter a count value (type 6), then enter the colon command with no range (type :s/old/new/g). Because you entered a count, Vim displays the command: :.,.+5s/old/new/g Default range For most commands, the default range is . (the current line, for example, :s/// substitutes in the current line). However, for :g// and :w the default is % (all lines). Selections A command like :123,145s/old/new/g substitutes in lines 123 to 145 inclusive, but what if you're not sure what the line numbers are? One method is to use marks: Type ma in the first line, then type mb in the last line (to set marks a and b). Then enter command :'a,'bs/old/new/g to substitute in lines from mark a to b, inclusive. Another method is to visually select lines, then enter a colon command (for example, :s/old/new/g). Note that you do not enter a range. However, because the command was entered while lines were selected, Vim displays the command as: :'<,'>s/old/new/g The range '<,'> is entered automatically to identify the lines that were last visually selected (they do not need to be visually selected now). For example, you might type vip to visually select "inner paragraph" (the paragraph holding the cursor). Then type :s/old/new/g to substitute in all lines in the selected paragraph. Deleting, copying and moving Ranges work with Ex commands (those typed after a colon, for example, :w). As well as the commands we've seen so far, it's handy to know how to use :d (delete lines), :t or :co (copy lines), and :m (move lines). The line numbers in a command are those before the command executes. In the earlier example which moved lines 21..25 to after 30, the "30" refers to the line number before the move occurred. Ranges with marks and searches In a range, a line number can be given as: *A mark (for example, 'x is the line containing mark x). *A search (for example, /pattern/ is the next line matching pattern). When using a mark, it must exist in the current buffer. Here are some examples using searches: ;:.,/green/co $ :Copy the lines from the current line to the next line containing 'green' (inclusive), to the end of the buffer. ;:/apples/,/apples/+1s/old/new/g :Replace all "old" in the next line in which the "apples" occurs, and the line following it. ;:/apples/;.1s/old/new/g :Same (.1 is .+1, and because ; was used, the cursor position is set to the line matching "apples" before interpreting the .+1). ;:/apples/,.100s/old/new/g :Replace all "old" in the next line in which "apples" occurs, and all lines up to and including 100 lines after the current line (where the command was entered). To do a replace in blocks identified by an initial and a final pattern: ;:/apples/,/peaches/ s/old/new/g :Replace all "old" in the first block that starts with "apples" and ends with "peaches". :/apples/ identifies the first line after the cursor containing "apples". :/peaches/ is similar (first line after the current line, not the first after "apples"). Be aware of backwards ranges. :The block is all lines from "apples" to "peaches", inclusive. ;:/apples/;/peaches/ s/old/new/g :Same, but "peaches" identifies the first occurrence after "apples". ;:/apples/,/peaches/ s/^/# /g :Insert "# " at the start of each line in the first block. ;:/apples/+1,/peaches/-1 s/^/# /g :Insert "# " at the start of each line inside the block. To do a global replace in all blocks with the same patterns, use :g: ;:g/apples/,/peaches/ s/^/# /g :Insert "# " at the start of each line in all identified blocks. ::g/apples/ identifies each line containing "apples". :In each such line, .,/peaches/ s/^/# /g is executed :(the . is assumed; it means the current line, where "apples" occurs). ;:g/^function!\? \(s:\)\?My/;/^endfunction/s/^/" / :This example is for a Vim script where functions start with function or function! and end with endfunction. :Insert "" " at the start of each line in each block. :All functions that start with function My or function s:My will be commented out. :The last line in each block is where endfunction first occurs (at the left margin), after where function My is found. Even more tricks are available; see . Summary: Comments I find this counter-intuitive to define a range with commas. Examples : 21,25 I would prefer 21-25 ... --July 19, 2016 A dash cannot be used because it refers to negative numbers, relative to the current line. The following uses range -3,-1 to yank (copy) the three line just before each line containing "password". :let @a='' :g/password/-3,-1y A :new :put a JohnBeckett (talk) 00:05, July 30, 2016 (UTC) ---- Is there more documentation on the concept of "count value", as in this sentence from the wiki above: "An easier method is to enter a count value (type 6), then enter the colon command with no range" ... ? --August 22, 2016 :See for "Count and Range". It has the example of 3:d being translated to .,.+2d. JohnBeckett (talk) 06:04, August 23, 2016 (UTC) ----